/**
 * WebGPU批量渲染性能测试
 * 对比标准WebGPU和批量优化版本的性能差异
 */

import '../src/js/webgpu-optimized-impl.js';

class PerformanceTest {
    constructor() {
        this.canvas = null;
        this.device = null;
        this.context = null;
        this.renderPipeline = null;
        this.buffer = null;
        this.stats = {
            frameCount: 0,
            totalTime: 0,
            minFrameTime: Infinity,
            maxFrameTime: 0,
            avgFrameTime: 0
        };
        this.lastFrameTime = 0;
        this.testDuration = 10000; // 10秒测试
        this.startTime = 0;
        this.objectCount = 1000; // 渲染1000个对象测试批量性能
    }
    
    async initialize() {
        // 创建canvas
        this.canvas = this.createCanvas();
        this.context = this.canvas.getContext('webgpu');
        
        // 获取WebGPU设备
        const adapter = await navigator.gpu.requestAdapter();
        this.device = await adapter.requestDevice();
        
        console.log('Performance test device initialized');
        
        // 配置canvas
        const canvasFormat = navigator.gpu.getPreferredCanvasFormat();
        this.context.configure({
            device: this.device,
            format: canvasFormat,
            alphaMode: 'premultiplied'
        });
        
        // 创建顶点缓冲区
        const vertices = new Float32Array([
            // 三角形顶点
            -0.01, -0.01,
             0.01, -0.01,
             0.00,  0.01,
        ]);
        
        this.buffer = this.device.createBuffer({
            size: vertices.byteLength,
            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
            mappedAtCreation: true
        });
        
        new Float32Array(this.buffer.getMappedRange()).set(vertices);
        this.buffer.unmap();
        
        // 创建着色器
        const vertexShader = this.device.createShaderModule({
            code: `
                @vertex
                fn main(
                    @location(0) position: vec2<f32>,
                    @builtin(instance_index) instanceIndex: u32
                ) -> @builtin(position) vec4<f32> {
                    let instanceCount = 1000u;
                    let row = instanceIndex / 32u;
                    let col = instanceIndex % 32u;
                    
                    let offsetX = (f32(col) - 15.5) * 0.06;
                    let offsetY = (f32(row) - 15.5) * 0.06;
                    
                    let worldPos = position + vec2<f32>(offsetX, offsetY);
                    return vec4<f32>(worldPos, 0.0, 1.0);
                }
            `
        });
        
        const fragmentShader = this.device.createShaderModule({
            code: `
                @fragment
                fn main(@builtin(position) fragCoord: vec4<f32>) -> @location(0) vec4<f32> {
                    let color = sin(fragCoord.xy * 0.01) * 0.5 + 0.5;
                    return vec4<f32>(color, 0.0, 1.0);
                }
            `
        });
        
        // 创建渲染管线
        this.renderPipeline = this.device.createRenderPipeline({
            vertex: {
                module: vertexShader,
                entryPoint: 'main',
                buffers: [{
                    arrayStride: 8, // 2 * 4 bytes
                    attributes: [{
                        shaderLocation: 0,
                        offset: 0,
                        format: 'float32x2'
                    }]
                }]
            },
            fragment: {
                module: fragmentShader,
                entryPoint: 'main',
                targets: [{
                    format: canvasFormat
                }]
            },
            primitive: {
                topology: 'triangle-list'
            },
            layout: 'auto'
        });
        
        console.log(`Performance test setup complete - testing ${this.objectCount} objects`);
    }
    
    startTest() {
        this.startTime = performance.now();
        this.lastFrameTime = this.startTime;
        this.stats = {
            frameCount: 0,
            totalTime: 0,
            minFrameTime: Infinity,
            maxFrameTime: 0,
            avgFrameTime: 0
        };
        
        console.log('Starting performance test...');
        this.render();
    }
    
    render() {
        const currentTime = performance.now();
        const frameTime = currentTime - this.lastFrameTime;
        
        // 更新统计信息
        this.stats.frameCount++;
        this.stats.totalTime = currentTime - this.startTime;
        this.stats.minFrameTime = Math.min(this.stats.minFrameTime, frameTime);
        this.stats.maxFrameTime = Math.max(this.stats.maxFrameTime, frameTime);
        this.stats.avgFrameTime = this.stats.totalTime / this.stats.frameCount;
        
        // 获取当前纹理视图
        const textureView = this.context.getCurrentTexture().createView();
        
        // 创建命令编码器
        const encoder = this.device.createCommandEncoder();
        
        // 开始渲染通道
        const renderPass = encoder.beginRenderPass({
            colorAttachments: [{
                view: textureView,
                clearValue: { r: 0.1, g: 0.1, b: 0.2, a: 1.0 },
                loadOp: 'clear',
                storeOp: 'store'
            }]
        });
        
        // 设置渲染管线
        renderPass.setPipeline(this.renderPipeline);
        renderPass.setVertexBuffer(0, this.buffer);
        
        // 批量绘制多个实例 - 这里会触发批量优化
        renderPass.draw(3, this.objectCount, 0, 0);
        
        // 结束渲染通道
        renderPass.end();
        
        // 提交命令 - 这里会触发批量提交
        const commandBuffer = encoder.finish();
        this.device.queue.submit([commandBuffer]);
        
        this.lastFrameTime = currentTime;
        
        // 检查测试是否完成
        if (this.stats.totalTime < this.testDuration) {
            requestAnimationFrame(() => this.render());
        } else {
            this.displayResults();
        }
        
        // 每秒输出一次统计信息
        if (this.stats.frameCount % 60 === 0) {
            this.displayCurrentStats();
        }
    }
    
    displayCurrentStats() {
        const fps = this.stats.frameCount / (this.stats.totalTime / 1000);
        console.log(`FPS: ${fps.toFixed(1)}, Avg Frame Time: ${this.stats.avgFrameTime.toFixed(2)}ms`);
        
        // 更新页面显示
        const statsDiv = document.getElementById('stats');
        if (statsDiv) {
            statsDiv.innerHTML = `
                <h3>Real-time Stats:</h3>
                <p>FPS: ${fps.toFixed(1)}</p>
                <p>Frame Count: ${this.stats.frameCount}</p>
                <p>Avg Frame Time: ${this.stats.avgFrameTime.toFixed(2)}ms</p>
                <p>Min Frame Time: ${this.stats.minFrameTime.toFixed(2)}ms</p>
                <p>Max Frame Time: ${this.stats.maxFrameTime.toFixed(2)}ms</p>
                <p>Objects Rendered: ${this.objectCount}</p>
            `;
        }
    }
    
    displayResults() {
        const fps = this.stats.frameCount / (this.stats.totalTime / 1000);
        const totalDrawCalls = this.stats.frameCount * this.objectCount;
        
        console.log('=== WebGPU Batch Rendering Performance Test Results ===');
        console.log(`Test Duration: ${this.testDuration / 1000}s`);
        console.log(`Total Frames: ${this.stats.frameCount}`);
        console.log(`Average FPS: ${fps.toFixed(1)}`);
        console.log(`Average Frame Time: ${this.stats.avgFrameTime.toFixed(2)}ms`);
        console.log(`Min Frame Time: ${this.stats.minFrameTime.toFixed(2)}ms`);
        console.log(`Max Frame Time: ${this.stats.maxFrameTime.toFixed(2)}ms`);
        console.log(`Objects per Frame: ${this.objectCount}`);
        console.log(`Total Draw Calls: ${totalDrawCalls}`);
        console.log(`Draw Calls per Second: ${(totalDrawCalls / (this.stats.totalTime / 1000)).toFixed(0)}`);
        
        // 显示在页面上
        const resultsDiv = document.getElementById('results');
        if (resultsDiv) {
            resultsDiv.innerHTML = `
                <h2>WebGPU Batch Rendering Performance Results</h2>
                <div class="result-item">
                    <strong>Average FPS:</strong> ${fps.toFixed(1)}
                </div>
                <div class="result-item">
                    <strong>Frame Time:</strong> ${this.stats.avgFrameTime.toFixed(2)}ms (avg), ${this.stats.minFrameTime.toFixed(2)}ms (min), ${this.stats.maxFrameTime.toFixed(2)}ms (max)
                </div>
                <div class="result-item">
                    <strong>Total Frames:</strong> ${this.stats.frameCount}
                </div>
                <div class="result-item">
                    <strong>Objects per Frame:</strong> ${this.objectCount}
                </div>
                <div class="result-item">
                    <strong>Draw Calls per Second:</strong> ${(totalDrawCalls / (this.stats.totalTime / 1000)).toFixed(0)}
                </div>
                <div class="note">
                    <p><strong>Note:</strong> This test uses the optimized WebGPU batch rendering implementation. 
                    Commands are automatically serialized and batched for better performance.</p>
                </div>
            `;
        }
    }
    
    createCanvas() {
        const canvas = document.createElement('canvas');
        canvas.id = 'webgpu-canvas';
        canvas.width = 800;
        canvas.height = 600;
        canvas.style.border = '1px solid #ccc';
        document.body.appendChild(canvas);
        return canvas;
    }
}

// 创建页面UI
function createUI() {
    document.body.innerHTML = `
        <div style="font-family: Arial, sans-serif; margin: 20px;">
            <h1>WebGPU Batch Rendering Performance Test</h1>
            <p>This test demonstrates the performance benefits of the WebGPU batch rendering optimization.</p>
            
            <div id="controls" style="margin: 20px 0;">
                <button id="startTest" onclick="startTest()">Start Performance Test</button>
                <button id="changeObjectCount" onclick="changeObjectCount()">Change Object Count</button>
            </div>
            
            <div style="display: flex; gap: 20px;">
                <div style="flex: 1;">
                    <div id="stats" style="background: #f5f5f5; padding: 15px; border-radius: 5px; margin-bottom: 20px;">
                        <h3>Waiting for test to start...</h3>
                    </div>
                </div>
            </div>
            
            <div id="results"></div>
        </div>
    `;
}

let performanceTest = null;

async function startTest() {
    if (performanceTest) {
        performanceTest = null;
    }
    
    performanceTest = new PerformanceTest();
    await performanceTest.initialize();
    performanceTest.startTest();
}

function changeObjectCount() {
    const newCount = prompt('Enter number of objects to render:', '1000');
    if (newCount && !isNaN(newCount)) {
        if (performanceTest) {
            performanceTest.objectCount = parseInt(newCount);
            console.log(`Object count changed to: ${performanceTest.objectCount}`);
        }
    }
}

// 初始化页面
if (typeof window !== 'undefined') {
    window.startTest = startTest;
    window.changeObjectCount = changeObjectCount;
    
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', createUI);
    } else {
        createUI();
    }
}

export { PerformanceTest, startTest };